#include <iostream>
#include <csignal>
#include <unistd.h>

void SignalHandler(int signum)
{
    std::cout << "pid: " << getpid() << ", tid: " << gettid() << std::endl;
    sleep(1);
    std::cout << "Interrupt signal (" << signum << ") received." << std::endl;
    sleep(1);
    // 清理并关闭
    // 终止程序
    exit(0);
}

int main(int argc, const char *argv[])
{
    std::cout << "pid: " << getpid() << ", tid: " << gettid() << std::endl;

    // 注册信号 SIGINT 和信号处理程序
    std::cout << SIG_ERR << "==" << std::signal(SIGINT,  SignalHandler) << std::endl;
    std::cout << SIG_ERR << "==" << std::signal(SIGSTOP, SignalHandler) << std::endl;
    std::cout << SIG_ERR << "==" << std::signal(SIGTERM, SignalHandler) << std::endl;
    std::cout << SIG_ERR << "==" << std::signal(SIGSEGV, SignalHandler) << std::endl;
    // *((char *)nullptr) = '\0';

    // SIG_DFL
    if (argc >= 2 && argv[1][0] == '0') {
        std::cout << "at 0" << std::endl;
        std::signal(SIGINT, SIG_DFL);
    }

    // SIG_IGN
    if (argc >= 2 && argv[1][0] == '1') {
        std::cout << "at 1" << std::endl;
        static auto func2 = [](int sig) {
            std::cout << "func2 received " << sig << "!" << std::endl;
            static int cnt = 0;
            cnt++;
            if (cnt >= 3) {
                exit(0);
            }
        };
        auto func1 = [](int sig) {
            std::cout << "func1 received " << sig << "!" << std::endl;
            std::signal(SIGTERM, func2);
        };
        std::signal(SIGTERM, SIG_IGN);
        std::signal(SIGINT, func1);
    }

    if (argc >= 2 && argv[1][0] == '2') {
        std::cout << "at 2" << std::endl;
        auto func = [](int sig, siginfo_t *info, void *) {
            std::cout << "func: " << sig << ", code: " << info->si_code << std::endl;
            exit(0);
        };
        struct sigaction sa = { .sa_sigaction = func };
        sigaction(SIGSEGV, &sa, nullptr);
        // *((char *)nullptr) = '\0';
        // char *str = (char *)"func: ";
        // str[0] = 1;
    }

    if (argc >= 2 && argv[1][0] == '3') {
        std::signal(SIGINT, SIG_IGN);
        execl("/usr/bin/sleep", "sleep", "25m", nullptr);
    }

    while (1) {
        std::cout << "Going to sleep...." << std::endl;
        sleep(1);
    }
    return 0;
}
